#include "unixHeader.h"
#include "token.hpp"
#include "hash.hpp"

#include "signup.srpc.h"
#include "workflow/WFFacilities.h"
#include <workflow/MySQLMessage.h>
#include <workflow/MySQLResult.h>
#include <ppconsul/agent.h>
#include <iostream>
#include <string>
using namespace std;

using namespace srpc;

// 创建一个等待组对象，初始计数为1
static WFFacilities::WaitGroup wait_group(1);
// 信号处理函数，用于结束等待组的等待
void sig_handler(int signo)
{
	wait_group.done();
}

// 实现用户注册服务的类，继承自 srpc 的 UserSignup::Service 接口
class UserSignupServiceImpl : public UserSignup::Service
{
public:
    // 注册服务的具体实现方法，被客户端调用
	void Signup(ReqSignup *request, RespSignup *response, srpc::RPCContext *ctx) override
	{
		// 服务器端的用户注册服务函数Signup被调用时，已经接收到了request
        //1. 解析请求
        string username = request->username();
        string password = request->password();
        cout << "username:" << username << endl;
        cout << "password:" << password << endl;

		//2. 对密码进行加密
        string salt("12345678");//这里应该是随机生成
        string encodedPassword(crypt(password.c_str(), salt.c_str()));
        cout << "mi wen:" << encodedPassword << endl;
        // 将用户信息存储到数据库MySQL中
        // 设置 MySQL 数据库的连接信息
        string mysqlurl("mysql://root:zz123456@localhost");
        // 创建一个 MySQL 异步任务，执行数据库操作
        auto mysqlTask = WFTaskFactory::create_mysql_task(mysqlurl, 1, 
        [response](WFMySQLTask * mysqltask){
            //0. 对任务的状态进行检测
            int state = mysqltask->get_state();
            int error = mysqltask->get_error();
            if(state != WFT_STATE_SUCCESS) {
                printf("%s\n", WFGlobal::get_error_string(state, error));
                return;
            }
            //1. 检测SQL语句是否存在语法错误
            // 获取 MySQL 任务的响应
            auto mysqlResp = mysqltask->get_resp();
            // 检查 MySQL 响应的数据包类型，如果是错误，则设置响应代码为404
            if(mysqlResp->get_packet_type() == MYSQL_PACKET_ERROR) {
                printf("ERROR %d: %s\n", mysqlResp->get_error_code(),
                       mysqlResp->get_error_msg().c_str());
                response->set_code(404);
                return;
            }
            // 使用 protocol 命名空间处理 MySQL 结果集
            using namespace protocol;
            MySQLResultCursor cursor(mysqlResp);
            // 检查 MySQL 结果集的状态，如果是 OK，则设置响应代码为200，表示成功
            if(cursor.get_cursor_status() == MYSQL_STATUS_OK) {
                //2. 成功写入数据库了
                printf("Query OK. %llu row affected.\n",cursor.get_affected_rows());
                response->set_code(200);
            } else {
                response->set_code(404);
            }
        });
        // 构建插入用户信息的 SQL 语句
        string sql("INSERT INTO cloudisk.tbl_user(user_name, user_pwd) VALUES('");
        sql += username + "', '" + encodedPassword + "')";
        cout << "sql:\n" << sql << endl;
        // 设置 MySQL 任务的查询语句，并将任务添加到上下文的任务序列中
        mysqlTask->get_req()->set_query(sql);
        ctx->get_series()->push_back(mysqlTask);
	}
};

// 引入 ppconsul 库的命名空间
using ppconsul::Consul;
using namespace ppconsul::agent;

// 定时器回调函数，用于定时发送心跳包
void timerCallback(WFTimerTask *timerTask) {
    printf("timerTask is running.\n");
    // 将定时器任务的用户数据转换为 Agent 对象指针
    Agent * pagent = (Agent*)timerTask->user_data;
    // 发送心跳包，表示服务继续存活
    pagent->servicePass("SignupService1");
    // 创建下一个定时器任务，间隔 5 秒执行一次心跳发送
    auto nextTask = WFTaskFactory::create_timer_task(5000 * 1000, timerCallback);
    nextTask->user_data = timerTask->user_data;
    series_of(timerTask)->push_back(nextTask);
}

int main()
{
    // 确保 Google Protocol Buffers 版本匹配
	GOOGLE_PROTOBUF_VERIFY_VERSION;
    // 定义 SRPC 服务端监听的端口号
	unsigned short port = 1412;
    // 创建 SRPC 服务器对象
	SRPCServer server;
    // 实例化用户注册服务的实现类
	UserSignupServiceImpl usersignup_impl;
    // 向 SRPC 服务器添加用户注册服务
	server.add_service(&usersignup_impl);
    // 启动 SRPC 服务器，监听指定端口
	server.start(port);

    // 创建 Consul 对象和 Agent 对象，用于注册服务和发送心跳
    Consul consul("127.0.0.1:8500", ppconsul::kw::dc = "dc1");
    Agent agent(consul);
    //向注册中心 Consul 注册微服务
    agent.registerService(
        kw::name = "SignupService1", // 服务名称
        kw::address = "127.0.0.1",   // 服务监听ip
        kw::port = 1412,             // 服务监听端口
        kw::id = "SignupService1",   // 服务ID
        kw::check = TtlCheck(std::chrono::seconds(10)) // 健康检查，每隔 10 秒发送一次心跳包
    );
    //取消注册
    //agent.deregisterService("SignupService1");
    // 发送一次心跳包，表示服务启动并存活
    agent.servicePass("SignupService1");
    //创建定时器，每隔5秒钟发送一次心跳包
    auto timerTask = WFTaskFactory::create_timer_task(5000 * 1000, timerCallback);
    timerTask->user_data = &agent;
    timerTask->start();

    // 等待信号，主线程进入阻塞状态，直到接收到信号
	wait_group.wait();
    // 停止 SRPC 服务器
	server.stop();
    // 关闭 Google Protocol Buffers 库
	google::protobuf::ShutdownProtobufLibrary();
	return 0;
}
